"""
配置加载器模块

负责加载和管理项目的各种配置文件。
"""

import yaml
from pathlib import Path
from typing import Dict, List, Any, Optional
from dataclasses import dataclass

from .models.data_model import WebsiteConfig
from .utils.logger import get_logger
from config.settings import PROJECT_ROOT


@dataclass
class GlobalConfig:
    """全局配置类"""
    max_concurrent_requests: int = 1
    default_delay: float = 1.0
    default_timeout: int = 30
    default_max_retries: int = 3
    output_format: str = "markdown"
    group_by_source: bool = True
    include_timestamp: bool = True
    filename_format: str = "scraped_data_{date}_{time}.md"
    log_level: str = "INFO"
    file_logging: bool = True
    console_logging: bool = True


class ConfigLoader:
    """配置加载器"""

    def __init__(self, config_dir: Optional[Path] = None):
        """
        初始化配置加载器

        Args:
            config_dir: 配置目录路径
        """
        self.config_dir = config_dir or (PROJECT_ROOT / "config")
        self.logger = get_logger('config_loader')

        # 配置文件路径
        self.urls_config_path = self.config_dir / "urls.yaml"

        self.logger.info(f"配置加载器初始化完成，配置目录: {self.config_dir}")

    def load_urls_config(self) -> Dict[str, Any]:
        """
        加载URL配置文件

        Returns:
            配置字典

        Raises:
            FileNotFoundError: 配置文件不存在时
            yaml.YAMLError: YAML解析错误时
        """
        if not self.urls_config_path.exists():
            raise FileNotFoundError(f"配置文件不存在: {self.urls_config_path}")

        try:
            with open(self.urls_config_path, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)

            self.logger.info(f"成功加载配置文件: {self.urls_config_path}")
            return config

        except yaml.YAMLError as e:
            self.logger.error(f"YAML解析错误: {e}")
            raise
        except Exception as e:
            self.logger.error(f"加载配置文件失败: {e}")
            raise

    def load_website_configs(self) -> List[WebsiteConfig]:
        """
        加载网站配置列表

        Returns:
            网站配置对象列表
        """
        config_data = self.load_urls_config()
        website_configs = []

        # 加载全局配置
        global_config = self._load_global_config(config_data.get('global_config', {}))

        # 加载网站配置
        websites = config_data.get('websites', {})

        for site_id, site_config in websites.items():
            try:
                # 合并全局配置
                merged_config = self._merge_configs(global_config, site_config)

                # 创建WebsiteConfig对象
                website_config = WebsiteConfig(
                    name=merged_config['name'],
                    url=merged_config['url'],
                    scraper_type=merged_config['scraper_type'],
                    selectors=merged_config.get('selectors', {}),
                    enabled=merged_config.get('enabled', True),
                    max_retries=merged_config.get('max_retries', global_config.default_max_retries),
                    timeout=merged_config.get('timeout', global_config.default_timeout),
                    delay=merged_config.get('delay', global_config.default_delay)
                )

                website_configs.append(website_config)
                self.logger.debug(f"加载网站配置: {website_config.name}")

            except Exception as e:
                self.logger.error(f"加载网站配置失败 {site_id}: {e}")
                continue

        self.logger.info(f"成功加载 {len(website_configs)} 个网站配置")
        return website_configs

    def _load_global_config(self, global_config_data: Dict[str, Any]) -> GlobalConfig:
        """
        加载全局配置

        Args:
            global_config_data: 全局配置数据

        Returns:
            全局配置对象
        """
        return GlobalConfig(
            max_concurrent_requests=global_config_data.get('max_concurrent_requests', 1),
            default_delay=global_config_data.get('default_delay', 1.0),
            default_timeout=global_config_data.get('default_timeout', 30),
            default_max_retries=global_config_data.get('default_max_retries', 3),
            output_format=global_config_data.get('output', {}).get('format', 'markdown'),
            group_by_source=global_config_data.get('output', {}).get('group_by_source', True),
            include_timestamp=global_config_data.get('output', {}).get('include_timestamp', True),
            filename_format=global_config_data.get('output', {}).get('filename_format', 'scraped_data_{date}_{time}.md'),
            log_level=global_config_data.get('logging', {}).get('level', 'INFO'),
            file_logging=global_config_data.get('logging', {}).get('file_logging', True),
            console_logging=global_config_data.get('logging', {}).get('console_logging', True)
        )

    def _merge_configs(self, global_config: GlobalConfig, site_config: Dict[str, Any]) -> Dict[str, Any]:
        """
        合并全局配置和站点配置

        Args:
            global_config: 全局配置
            site_config: 站点配置

        Returns:
            合并后的配置
        """
        merged = site_config.copy()

        # 应用全局配置的默认值
        if 'max_retries' not in merged:
            merged['max_retries'] = global_config.default_max_retries

        if 'timeout' not in merged:
            merged['timeout'] = global_config.default_timeout

        if 'delay' not in merged:
            merged['delay'] = global_config.default_delay

        return merged

    def get_enabled_websites(self) -> List[WebsiteConfig]:
        """
        获取启用的网站配置

        Returns:
            启用的网站配置列表
        """
        all_configs = self.load_website_configs()
        enabled_configs = [config for config in all_configs if config.enabled]

        self.logger.info(f"找到 {len(enabled_configs)} 个启用的网站")
        return enabled_configs

    def validate_config(self, config: WebsiteConfig) -> bool:
        """
        验证配置有效性

        Args:
            config: 网站配置

        Returns:
            是否有效
        """
        try:
            # 检查必填字段
            if not config.name or not config.url or not config.scraper_type:
                self.logger.error(f"配置缺少必填字段: {config.name}")
                return False

            # 检查URL格式
            if not config.url.startswith(('http://', 'https://')):
                self.logger.error(f"无效的URL格式: {config.url}")
                return False

            # 检查选择器配置
            if not config.selectors:
                self.logger.warning(f"网站 {config.name} 没有配置选择器")

            return True

        except Exception as e:
            self.logger.error(f"验证配置失败: {e}")
            return False

    def reload_config(self) -> List[WebsiteConfig]:
        """
        重新加载配置

        Returns:
            重新加载的网站配置列表
        """
        self.logger.info("重新加载配置")
        return self.load_website_configs()


# 创建全局配置加载器实例
config_loader = ConfigLoader()
